import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:json_annotation/json_annotation.dart';

part 'app_types.freezed.dart';
part 'app_types.g.dart';

/**
 * 同步状态枚举
 */
enum SyncStatus {
  @JsonValue('local')
  local,
  @JsonValue('pending')
  pending,
  @JsonValue('synced')
  synced,
  @JsonValue('syncing')
  syncing,
  @JsonValue('error')
  error,
}

/**
 * 通知类型枚举
 */
enum NotificationType {
  @JsonValue('success')
  success,
  @JsonValue('error')
  error,
  @JsonValue('warning')
  warning,
  @JsonValue('info')
  info,
}

/**
 * 文件夹数据模型
 */
@freezed
class Folder with _$Folder {
  const factory Folder({
    required int id,
    required String name,
    @Default(0) int count,
    @Default(false) bool isDefault,
    @Default(false) bool isShared,
    int? parentId,
    @Default(0) int sortOrder,
    required DateTime createdAt,
    required DateTime updatedAt,
    @Default(SyncStatus.local) SyncStatus syncStatus,
    String? serverId,
    @Default([]) List<Folder> children,
    @Default(false) bool isExpanded,
    String? shareLink,
    String? sharePassword,
  }) = _Folder;

  factory Folder.fromJson(Map<String, dynamic> json) => _$FolderFromJson(json);

  /**
   * 创建默认的"全部笔记"文件夹
   */
  static Folder get allNotes => Folder(
        id: 1,
        name: '全部笔记',
        isDefault: true,
        createdAt: DateTime.now(),
        updatedAt: DateTime.now(),
      );

  /**
   * 创建默认的"未分类"文件夹
   */
  static Folder get uncategorized => Folder(
        id: 2,
        name: '未分类',
        isDefault: true,
        createdAt: DateTime.now(),
        updatedAt: DateTime.now(),
      );
}

/**
 * 笔记数据模型
 */
@freezed
class Note with _$Note {
  const factory Note({
    required int id,
    required String title,
    required String content,
    int? folderId,
    required DateTime createdAt,
    required DateTime updatedAt,
    @Default(SyncStatus.local) SyncStatus syncStatus,
    String? serverId,
    @Default([]) List<String> tags,
    @Default(false) bool isShared,
    String? shareLink,
    String? sharePassword,
  }) = _Note;

  factory Note.fromJson(Map<String, dynamic> json) => _$NoteFromJson(json);

  /**
   * 创建新笔记
   */
  factory Note.create({
    required String title,
    required String content,
    int? folderId,
  }) {
    final now = DateTime.now();
    return Note(
      id: now.millisecondsSinceEpoch,
      title: title,
      content: content,
      folderId: folderId,
      createdAt: now,
      updatedAt: now,
    );
  }
}

/**
 * 应用数据状态
 */
@freezed
class AppData with _$AppData {
  const factory AppData({
    @Default([]) List<Folder> folders,
    @Default([]) List<Note> notes,
    @Default('1') String currentFolderId,
    int? currentNoteId,
    @Default('') String searchQuery,
    @Default(false) bool showSettings,
  }) = _AppData;

  factory AppData.fromJson(Map<String, dynamic> json) => _$AppDataFromJson(json);
}

/**
 * 应用通知
 */
@freezed
class AppNotification with _$AppNotification {
  const factory AppNotification({
    required String id,
    @Default(NotificationType.info) NotificationType type,
    String? title,
    required String message,
    Duration? duration,
    @Default(true) bool closable,
    @Default(false) bool isRead,
    required DateTime createdAt,
  }) = _AppNotification;

  factory AppNotification.fromJson(Map<String, dynamic> json) =>
      _$AppNotificationFromJson(json);

  /**
   * 创建成功通知
   */
  factory AppNotification.success({
    String? title,
    required String message,
    Duration? duration,
  }) {
    return AppNotification(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      type: NotificationType.success,
      title: title,
      message: message,
      duration: duration ?? const Duration(seconds: 3),
      createdAt: DateTime.now(),
    );
  }

  /**
   * 创建错误通知
   */
  factory AppNotification.error({
    String? title,
    required String message,
    Duration? duration,
  }) {
    return AppNotification(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      type: NotificationType.error,
      title: title,
      message: message,
      duration: duration ?? const Duration(seconds: 5),
      createdAt: DateTime.now(),
    );
  }

  /**
   * 创建警告通知
   */
  factory AppNotification.warning({
    String? title,
    required String message,
    Duration? duration,
  }) {
    return AppNotification(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      type: NotificationType.warning,
      title: title,
      message: message,
      duration: duration ?? const Duration(seconds: 4),
      createdAt: DateTime.now(),
    );
  }

  /**
   * 创建信息通知
   */
  factory AppNotification.info({
    String? title,
    required String message,
    Duration? duration,
  }) {
    return AppNotification(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      type: NotificationType.info,
      title: title,
      message: message,
      duration: duration ?? const Duration(seconds: 3),
      createdAt: DateTime.now(),
    );
  }
}

/**
 * 通知配置
 */
@freezed
class NotificationConfig with _$NotificationConfig {
  const factory NotificationConfig({
    @Default(NotificationType.info) NotificationType type,
    String? title,
    required String message,
    @Default(3000) int duration,
    @Default(true) bool closable,
  }) = _NotificationConfig;

  factory NotificationConfig.fromJson(Map<String, dynamic> json) =>
      _$NotificationConfigFromJson(json);
}

/**
 * 同步结果
 */
@freezed
class SyncResult with _$SyncResult {
  const factory SyncResult({
    required bool success,
    @Default(0) int failedCount,
    @Default(0) int totalCount,
    String? message,
  }) = _SyncResult;

  factory SyncResult.fromJson(Map<String, dynamic> json) =>
      _$SyncResultFromJson(json);
}

/**
 * 同步状态信息
 */
@freezed
class SyncStatusInfo with _$SyncStatusInfo {
  const factory SyncStatusInfo({
    @Default(false) bool hasPendingData,
    @Default(0) int pendingCount,
    @Default(0) int folders,
    @Default(0) int notes,
  }) = _SyncStatusInfo;

  factory SyncStatusInfo.fromJson(Map<String, dynamic> json) =>
      _$SyncStatusInfoFromJson(json);
}